home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
editors
/
mjovesrc.zoo
/
scandir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-04
|
5KB
|
229 lines
/***************************************************************************
* This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
* is provided to you without charge, and with no warranty. You may give *
* away copies of JOVE, including sources, provided that this notice is *
* included in all the files. *
***************************************************************************/
/*
* This file is used as a compiled module by Jove and also included as
* source in recover.c
*/
#ifndef TUNED
# include "jove.h"
#endif
#include "scandir.h"
#ifdef F_COMPLETION
#ifdef MSDOS
# include <dos.h>
# include <search.h>
#endif
#ifdef UNIX
# include <sys/stat.h>
# ifdef M_XENIX
# include <sys/ndir.h>
# ifndef dirent
# define dirent direct
# endif
# else
# ifdef DIRENT
# include <dirent.h>
# else
# include <sys/dir.h>
# ifndef dirent
# define dirent direct
# endif
# endif DIRENT
# endif /* M_XENIX */
#endif
#ifdef UNIX
#define DIRSIZE(entry) (strlen((entry)->d_name))
#if !defined(BSD_DIR) && !defined(DIRENT)
typedef struct {
int d_fd; /* File descriptor for this directory */
} DIR;
private int
closedir(dp)
DIR *dp;
{
(void) close(dp->d_fd);
free((char *) dp);
return 0; /* don't know how to fail */
}
private DIR *
opendir(dir)
char *dir;
{
DIR *dp = (DIR *) emalloc(sizeof *dp);
struct stat stbuf;
if ((dp->d_fd = open(dir, 0)) == -1)
return NULL;
if ((fstat(dp->d_fd, &stbuf) == -1) || !(stbuf.st_mode & S_IFDIR)) {
closedir(dp);
return NULL; /* this isn't a directory! */
}
return dp;
}
private dirent *
readdir(dp)
DIR *dp;
{
static dirent dir;
do {
if (read(dp->d_fd, (UnivPtr) &dir, sizeof dir) != sizeof dir)
return NULL;
#if defined(elxsi) && defined(SYSV)
/*
* Elxsi has a BSD4.2 implementation which may or may not use
* `twisted inodes' ... Anyone able to check?
*/
} while (*(unsigned short *)&dir.d_ino == 0);
#else
} while (dir.d_ino == 0);
#endif
return &dir;
}
#endif /* ! BSD_DIR */
/* Scandir returns the number of entries or -1 if the directory cannoot
be opened or malloc fails. */
int
jscandir(dir, nmptr, qualify, sorter)
char *dir;
char ***nmptr;
int (*qualify) proto((char *));
int (*sorter) proto((UnivConstPtr, UnivConstPtr));
{
DIR *dirp;
struct dirent *entry;
char **ourarray;
unsigned int nalloc = 10,
nentries = 0;
if ((dirp = opendir(dir)) == NULL)
return -1;
ourarray = (char **) emalloc(nalloc * sizeof (char *));
while ((entry = readdir(dirp)) != NULL) {
if (qualify != NULL && (*qualify)(entry->d_name) == 0)
continue;
if (nentries == nalloc) {
ourarray = (char **) realloc((UnivPtr) ourarray, (nalloc += 10) * sizeof (char *));
if (ourarray == NULL)
complain("[Malloc failed: cannot scandir]");
}
ourarray[nentries] = (char *) emalloc(DIRSIZE(entry) + 1);
null_ncpy(ourarray[nentries], entry->d_name, (size_t) DIRSIZE(entry));
nentries += 1;
}
closedir(dirp);
if ((nentries + 1) != nalloc)
ourarray = (char **) erealloc((UnivPtr) ourarray,
((nentries + 1) * sizeof (char *)));
if (sorter != NULL)
qsort((UnivPtr) ourarray, nentries, sizeof (char **), sorter);
*nmptr = ourarray;
ourarray[nentries] = NULL; /* guaranteed NULL pointer */
return nentries;
}
#endif /* UNIX */
#ifdef MSDOS
# define DIRSIZE(entry) strlen((entry).name)
/* Scandir returns the number of entries or -1 if the directory cannot
be opened or malloc fails. */
unsigned int fmask = _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR;
int
jscandir(dir, nmptr, qualify, sorter)
char *dir;
char ***nmptr;
int (*qualify) proto((char *));
int (*sorter) proto((UnivConstPtr, UnivConstPtr));
{
char dirname[FILESIZE];
struct find_t entry;
char *ptr;
char **ourarray;
unsigned int nalloc = 10,
nentries = 0;
strcpy(dirname, dir);
ptr = &dirname[strlen(dirname)-1];
if ((dirname[1] == ':' && !dirname[2]) || (*ptr == '/') || (*ptr == '\\'))
strcat(dirname, "*.*");
else
strcat(dirname, "/*.*");
if (_dos_findfirst(dirname, fmask, &entry))
return -1;
if ((ourarray = (char **) emalloc(nalloc * sizeof (char *))) == NULL)
do {
if ((fmask == 0x10) && !(entry.attrib&fmask))
continue;
strlwr(entry.name);
if (qualify != NULL && (*qualify)(entry.name) == 0)
continue;
if (nentries == nalloc) {
ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
if (ourarray == NULL)
complain("[Malloc failed: cannot scandir]");
}
ourarray[nentries] = (char *) emalloc(DIRSIZE(entry) + 1);
null_ncpy(ourarray[nentries], entry.name, (int) DIRSIZE(entry));
nentries++;
} while (_dos_findnext(&entry) == 0);
if ((nentries + 1) != nalloc)
ourarray = (char **) erealloc((char *) ourarray,
((nentries + 1) * sizeof (char *)));
if (sorter != (int (*)())NULL)
qsort((char *) ourarray, nentries, sizeof (char **), sorter);
*nmptr = ourarray;
ourarray[nentries] = NULL; /* guaranteed NULL pointer */
return nentries;
}
#endif /* MSDOS */
void
freedir(nmptr, nentries)
char ***nmptr;
int nentries;
{
char **ourarray = *nmptr;
while (--nentries >= 0)
free((UnivPtr) *ourarray++);
free((UnivPtr) *nmptr);
*nmptr = NULL;
}
int
alphacomp(a, b)
UnivConstPtr a,
b;
{
return strcmp(*(const char **)a, *(const char **)b);
}
#endif /* F_COMPLETION */